import threading
from modules.camera import CameraModel
from modules.collection import CollectionModel
from modules.dataset import DatasetModel
from services.collect import CollectionService
from core import db, app
from datetime import datetime
from pathlib import Path
from typing import Optional, Tuple, Dict, Any, Union
import os
import cv2

class RtspCollectionService(CollectionService):
    def __init__(self, collection: CollectionModel, event: threading.Event) -> None:
        self.collection = collection
        self.event = event

        self.dataset = DatasetModel.query.get(self.collection.ds_id)
        self.out_path = Path(app.config['DATASET_PATH']) / self.dataset.path
        self.out_path.mkdir(parents=True, exist_ok=True)

        self.camera = CameraModel.query.get(self.collection.camera_id)

    def start(self):
        try:

            #加载现有图片
            self.load_frame(
                ds_id=self.dataset.id,
                canmera_id=self.camera.id
            )

            self.extract_frames(
                video_url=self.camera.url,
                collection_id=self.collection.id,
                ds_id=self.dataset.id,
                camera_id=self.camera.id,
                output_dir=self.out_path,
                resize=None,
                frame_format="jpg",
            )

            # 停止
            # CollectionModel.query.filter_by(id=self.collection.id).update({
            #     'status': '4',
            #     'end_time': datetime.now()
            # })
            # db.session.commit()
        except Exception as e:
            print(f"Error in extract_frames: {e}")
            raise e

    def extract_frames(
        self,
        video_url: Union[str, Path],
        collection_id: int,
        ds_id: int,
        camera_id: int,
        output_dir: Union[str, Path],
        frame_format: str = "jpg",
        resize: Optional[Tuple[int, int]] = None,
    ) -> Dict[str, Any]:
        """
        从视频中提取帧

        Args:
            video_path: 视频文件路径
            output_dir: 输出目录
            interval: 提取帧的间隔（秒）
            max_frames: 最大提取帧数
            resize: 调整大小 (width, height)
            frame_format: 帧图像格式 ("jpg", "png")
            quality: 图像质量 (1-100)，仅对jpg有效
            include_timestamp: 是否在文件名中包含时间戳

        Returns:
            Dict: 提取结果，包括提取的帧数量、帧路径列表等
        """
        try:
            # 确保输出目录存在
            output_dir = Path(output_dir)
            os.makedirs(output_dir, exist_ok=True)

            # 打开视频
            print(f"打开视频: {video_url}")
            self.cap = cv2.VideoCapture(str(video_url))
            if not self.cap.isOpened():
                raise ValueError(f"无法打开视频: {video_url}")

            # 获取视频信息
            fps = self.cap.get(cv2.CAP_PROP_FPS)
            frame_count = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))
            duration = frame_count / fps if fps > 0 else 0

            # 提取帧
            extracted_frames = []
            extracted_count = 0

            while not self.event.is_set():

                # 读取帧
                ret, frame = self.cap.read()
                if not ret:
                    break

                # 调整大小
                if resize is not None:
                    frame = cv2.resize(frame, resize)

                # 保存帧
                self.add_frame(
                    output_dir=str(output_dir),
                    ds_id=ds_id,
                    canmera_id=camera_id,
                    frame=frame
                )

            self.stop();
            return {
                "total_frames": frame_count,
                "extracted_frames": extracted_count,
                "frames": extracted_frames,
                "video_info": {
                    "fps": fps,
                    "duration": duration,
                    "frame_count": frame_count
                }
            }
        except Exception as e:
            print(f"提取视频帧失败: {e}")
            raise e
            #logger.error(f"提取视频帧失败: {str(e)}")
            #raise HTTPException(status_code=500, detail=f"提取视频帧失败: {str(e)}")

    def stop(self):
        # 释放视频对象
        self.cap.release()
        self.collection.status = '4'
        self.collection.end_time = datetime.now()
        db.session.add(self.collection)
        db.session.commit()
